﻿// -------------------------------------------------------------------------
//    @FileName         :    NFBagPageOp.h
//    @Author           :    gaoyi
//    @Date             :    2024/12/20
//    @Email            :    445267987@qq.com
//    @Module           :    NFItemOperator
//
// -------------------------------------------------------------------------

// --- 文件总结 ---------------------------------------------------------------
// `NFBagPageOpMgr` 是背包页签操作管理器的具体实现类：
// - 继承自 NFBagPageOpMgrInterface，提供完整的背包操作功能
// - 集成金钱操作（NFMoneyOp），统一管理物品和货币的变更
// - 提供提交、同步、奖励通知等功能
// - 与 NFPlayer 紧密集成，处理玩家背包相关的所有操作
// ---------------------------------------------------------------------------

#pragma once

#include <NFMoneyOp.h>
#include "NFComm/NFCore/NFPlatform.h"
#include "NFLogicCommon/BagPage/NFBagPageOpMgrInterface.h"

/**
 * @brief 背包页签操作管理器（玩家版本）
 * 继承自 NFBagPageOpMgrInterface，提供完整的背包和货币操作功能
 */
class NFBagPageOpMgr : public NFBagPageOpMgrInterface
{
public:
    /**
     * @brief 构造函数
     * @param pPlayer 玩家指针
     * @param iOpReson 操作原因
     * @param bNeedCommit 是否需要提交（默认true）
     */
    NFBagPageOpMgr(NFPlayer* pPlayer, int iOpReson, bool bNeedCommit = true);

    /**
     * @brief 析构函数
     */
    ~NFBagPageOpMgr() override;

public:
    /**
     * @brief 提交所有操作，将操作结果应用到真实容器（只允许执行一次）
     * @param bSyncToClient 是否将变更同步给客户端
     * @return 0成功，非0失败
     */
    int Commit(bool bSyncToClient = true) override;
    
    /**
     * @brief 获取指定背包页签
     * @param iBagType 背包页签类型
     * @return 背包页签指针（可能为nullptr）
     */
    NFBagPage* GetBagPage(int iBagType) override;
    
    /**
     * @brief 添加常用的随身容器
     * @return 0成功，非0失败
     */
    int AddAllBagPage() override;
    
    /**
     * @brief 获取金钱数量
     * @param moneyType 金钱类型
     * @return 金钱数量
     */
    int64_t GetMoneyNumber(int moneyType) override;
    
    /**
     * @brief 设置金钱数量
     * @param moneyType 金钱类型
     * @param num 金钱数量
     * @return 0成功，非0失败
     */
    int SetMoneyNumber(int moneyType, int64_t num) override;
    
    /**
     * @brief 增加金钱
     * @param enMoneyType 金钱类型
     * @param llMoney 想要增加的金钱数（must >= 0）
     * @param pAddedNum 输出实际增加数量（=nullptr 全部增加，!=nullptr 尽可能增加）
     * @return 0成功，非0失败
     */
    int IncMoney(int enMoneyType, int llMoney, int* pAddedNum = nullptr) override;
    
    /**
     * @brief 减少金钱
     * @param enMoneyType 金钱类型
     * @param llMoney 想要减少的金钱数（must >= 0）
     * @param piDelNum 输出实际减少数量（=nullptr 全部减少，!=nullptr 尽可能减少）
     * @return 0成功，非0失败
     */
    int DecMoney(int enMoneyType, int llMoney, int* piDelNum = nullptr) override;
    
    /**
     * @brief 背包满时添加物品的特殊处理
     * @param stWillAddItemData 待添加物品数据
     * @param iLeftAddNum 剩余要添加的数量
     * @param iAddNum 输出实际添加数量
     * @return 0成功，非0失败
     */
    int AddItemWhenBagFull(const WillAddItemData& stWillAddItemData, int iLeftAddNum, int& iAddNum) override;
    
    /**
     * @brief 背包满时添加物品的特殊处理（物品对象版本）
     * @param pItem 物品对象
     * @param iLeftAddNum 剩余要添加的数量
     * @param iAddNum 输出实际添加数量
     * @return 0成功，非0失败
     */
    int AddItemWhenBagFull(const NFGridItem* pItem, int iLeftAddNum, int& iAddNum) override;
public:
    /**
     * @brief 发送奖励通知
     * @param notShow 是否不显示
     * @param type 类型
     * @param iParam 参数
     * @return 0成功，非0失败
     */
    int SendRewardNtf(bool notShow, int type, int iParam);
    
    /**
     * @brief 填充背包添加物品通知消息
     * @param pNtf 输出通知消息
     * @return 0成功，非0失败
     */
    int FillPackageInfoForAdd(proto_ff::Proto_CSRoleItemNtf* pNtf);
    
    /**
     * @brief 填充背包删除物品通知消息
     * @param pNtf 输出通知消息
     * @return 0成功，非0失败
     */
    int FillPackageInfoForDel(proto_ff::Proto_CSRoleItemNtf* pNtf);
private:
    /**
     * @brief 提交所有操作到玩家（内部实现）
     * @return 0成功，非0失败
     */
    int CommitToPlayer();
    
    /**
     * @brief 将变更同步给玩家客户端
     * @return 0成功，非0失败
     */
    int SyncToPlayer();

    /**
     * @brief 预检查提交
     * @return 0成功，非0失败
     */
    int PreCheckCommit();

    /**
     * @brief 将背包变更同步给客户端
     * @param pPlayer 玩家指针
     * @return 0成功，非0失败
     */
    int SyncPackageToPlayer(NFPlayer* pPlayer);
public:
    /**
     * @brief 获取玩家指针（一定存在，不用检查）
     * @return 玩家指针
     */
    NFPlayer* GetPlayer() { return m_pPlayer; }
protected:
    /** @brief 玩家指针 */
    NFPlayer* m_pPlayer;
    /** @brief 金钱操作器 */
    NFMoneyOp m_moneyOp;
};
